/*
 * miniFreeRTOS
 * Copyright (c) 2024- yanl1229@163.com.
 * Written by yanl1229
 *
 * This code is licensed under the GPL.
 */

#ifndef QUEUE_H
#define QUEUE_H

#include "list.h"
#include "task.h"

/* Constants used with the read_lock and write_lock structure members. */
#define queueUNLOCKED             ( ( int8_t ) -1 )
#define queueLOCKED_UNMODIFIED    ( ( int8_t ) 0 )
#define queueINT8_MAX             ( ( int8_t ) 127 )

/*
 * 消息队列管理结构
 */
struct msg_queue
{
    int8_t *front;                          /* 队列中存放消息的位置 */
    int8_t *tail;                           /* 指向队列中存放消息的最后位置 */
    int8_t *write_pos;                      /* 下一个可存写消息的位置 */
    int8_t *read_pos;                       /* 下一个可存读消息的位置 */

    list_head q_senders;                    /* 等待发送任务列表，队列满导致像向消息队列发送的任务，都会阻塞加到该队列上 */
    list_head q_receivers;                  /* 等待接收任务列表，队列空导致像从消息队列读消息的任务，都会阻塞加到该该队列上 */

    volatile uint32_t messages;             /* 当前队列中的消息数 */
    uint32_t limit;                         /* 队列的长度，其实是保存队列元素的个数 */
    uint32_t item_size;                     /* 消息的长度 */

    volatile int8_t read_lock;              /* 队列接收锁计数器(可嵌套) */
    volatile int8_t write_lock;             /* 队列发送锁计数器(可嵌套) */
};

/**
 * 动态创建队列
 * @uxQueueLength: 队列中存放消息个数
 * @item_size:    队列消息的长度
 */
extern struct msg_queue * queue_create(uint32_t uxQueueLength, uint32_t item_size);


/**
 * 向队列发送消息
 * @msg: 消息
 * @timeout: 等待发送超时tick
 */
extern uint32_t queue_write(struct msg_queue * queue, void *msg);
extern uint32_t queue_write_noblock(struct msg_queue * queue, void *msg);

extern uint32_t queue_read(struct msg_queue * queue, void *buff);
extern uint32_t queue_read_noblock(struct msg_queue * queue, void *buff);

extern void queue_delete(struct msg_queue * queue);

extern uint32_t queue_write_irq(struct msg_queue *queue, void *msg);

extern uint32_t queue_read_irq(struct msg_queue *queue, void *msg);

#endif /* QUEUE_H */
